/*
 * Copyright (c) 2011 Imre Fazekas.
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * Neither the name of the Brillien nor the names of its
 * terms and concepts may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package com.vii.brillien.kernel.axiom.transport;

import com.vii.brillien.kernel.BrillienException;
import com.vii.brillien.kernel.axiom.sso.Session;

import java.util.Map;

/**
 * Data representation of an abstract Communication.
 */
public interface Communication {

    /**
     * According to the specification of Powerobject model, these constants defines the basic types of communication.
     */
    final int           TYPE_UNDEFINED      = -1;
    final int           TYPE_UNKOWN         = 0;
    final int           TYPE_GET            = 1;
    final int           TYPE_AGET           = 2;
    final int           TYPE_SET            = 3;
    final int           TYPE_DELEGATED_SET  = 4;
    final int           TYPE_RESULT         = 5;
    final int           TYPE_ERROR          = 6;

    final String        DEFAULT_FLOW_ID = "Unknown";

    String              getId();

    void                setId(String id);


    int                 getMessageType();

    void                setMessageType(int messageType);


    String              getSender();

    void                setSender(String sender);


    String              getRecipient();

    void                setRecipient(String recipient);


    String              getFlowID();

    void                setFlowID(String flowID);


    Session             getSession();

    void                setSession(Session session);


    String              getApiKey();

    void                setApiKey(String apiKey);


    String              getSubject();

    void                setSubject(String subject);


    String              getRedirectEntityName();

    void                setRedirectEntityName(String redirectEntityName);


    String              getRedirectMessage();

    void                setRedirectMessage(String redirectMessage);


    Long                getRequestTime();

    void                setRequestTime(Long requestTime);


    Long                getResponseTime();

    void                setResponseTime(Long responseTime);

    Map<String, Object> getParameters();

    void                setParameters(Map<String, Object> parameters);

    Map<String, Object> acquireParameters(Map<String, Class> types) throws BrillienException;

    
    <T> T               getResponse();

    void                setResponse(Object response);

    <T> T               acquireResponse(Class<T> type) throws BrillienException;
    <T> T               acquireResponse(Class<T> type, Map<String, Class> typeHint) throws BrillienException;
    <T> T               acquireResponse(Map<String, Class> typeHint) throws BrillienException;
    <T> T               acquireResponse(String typeHint, Class hintClass) throws BrillienException;
    <T> T               acquireResponse(Class<T> type, String typeHint, Class hintClass) throws BrillienException;

    int                 getOriginalType();

    void                setOriginalType(int originalType);


    String              getOriginalId();

    void                setOriginalId(String id);


    Integer             getErrorCode() ;

    void                setErrorCode(Integer errorCode);


    Object              getErrorValue();

    void                setErrorValue(Object errorValue);


    boolean             isAnswerTo(Communication msg);

    /**
     * Application or chanel specific extension can be added to a communication
     */
    void                addExtension(String key, Object value);

    /**
     * Tells whether the given excension exists
     */
    boolean             hasExcension(String key);

    /**
     * Retrieves application or chanel specific extension
     */
    <T> T               getExtension(String key);

}
